home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / gcc / ixemlsrc.lha / ixemul / library / chdir.c < prev    next >
C/C++ Source or Header  |  1996-03-13  |  5KB  |  197 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  chdir.c,v 1.1.1.1 1994/04/04 04:30:15 amiga Exp
  20.  *
  21.  *  chdir.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:15  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.3  1992/08/09  20:43:22  amiga
  26.  *  change to use 2.x header files by default
  27.  *
  28.  *  Revision 1.2  1992/05/22  01:45:51  mwild
  29.  *  remove ix_panic call, seems to happen more than I thought
  30.  *
  31.  * Revision 1.1  1992/05/14  19:55:40  mwild
  32.  * Initial revision
  33.  *
  34.  */
  35.  
  36. #define KERNEL
  37. #include "ixemul.h"
  38. #include "kprintf.h"
  39.  
  40. /* this one is for Mike B. Smith ;-) */
  41.  
  42. void set_dir_name_from_lock(BPTR lock)
  43. {
  44.   char *buf = (char *) kmalloc (MAXPATHLEN);
  45.  
  46.   if (buf)
  47.     {
  48.       /* NOTE: This shortcuts any symlinks. But then, Unix does the
  49.        *       same, and a shell that wants to be smart about symlinks,
  50.        *       has to track chdir()s itself as well */
  51.       if (NameFromLock (lock, buf, MAXPATHLEN))
  52.         SetCurrentDirName (buf);
  53.       kfree (buf);
  54.     }
  55. }
  56.  
  57. /*
  58.  * Checks if pathname "name1" is above
  59.  * "name" in directory structure.
  60.  * Lock()/Unlock() are used instead of __lock/__unlock
  61.  * because this routine seems too loop if name2 is a subdir of name1
  62.  */
  63. static short
  64. dirisparent (char *name1, char *name2) {
  65.     short ret = 0;
  66.     BPTR lock1;
  67.  
  68.     lock1 = Lock (name1, SHARED_LOCK);
  69.     if (lock1) {
  70.     BPTR lock2;
  71.  
  72.     lock2 = Lock (name2, SHARED_LOCK);
  73.     if (lock2) {
  74.  
  75.         switch (SameLock (lock1, lock2)) {
  76.  
  77.         case LOCK_DIFFERENT:
  78.         break;
  79.  
  80.         case LOCK_SAME:
  81.             ret = 2;
  82.         break;
  83.  
  84.         case LOCK_SAME_VOLUME:
  85.         {
  86.             BPTR l;
  87.  
  88.             while (lock2) {
  89.             l = lock2;
  90.             lock2 = ParentDir (l);
  91.             UnLock (l);
  92.             if (SameLock (lock1, lock2) == LOCK_SAME) {
  93.                 ret = 1;
  94.                 break;
  95.             }
  96.             }
  97.             break;
  98.         }
  99.         }
  100.         UnLock (lock2);
  101.     }
  102.     UnLock (lock1);
  103.     }
  104.     return ret;
  105. }
  106.  
  107. /* if we change our directory, we have to remember the original cd, when
  108.  * the process was started, because we're not allowed to unlock this
  109.  * lock, since we didn't obtain it. */
  110.  
  111. int chdir (char *path)
  112. {
  113.   BPTR oldlock, newlock;
  114.   int error = 0;
  115.   int omask;
  116.   struct stat stb;
  117.   /* Sigh... CurrentDir() is a DOS-library function, it would probably be
  118.    * ok to just use pr_CurrentDir, but alas, this way we're conformant to
  119.    * programming style guidelines, but we pay the overhead of locking dosbase
  120.    */
  121.  
  122.   /* chdir("/") with u.u_root_directory set, chdir's to root directory */
  123.   if (!strcmp("/",path) && *u.u_root_directory)
  124.     path = u.u_root_directory;
  125.  
  126.   if (syscall (SYS_stat, path, &stb) == 0 && !(stb.st_mode&S_IFDIR))
  127.   {
  128.     errno = ENOTDIR;
  129.     KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  130.     return -1;
  131.   }
  132.  
  133.   omask = syscall (SYS_sigsetmask, ~0);
  134.  
  135.   newlock = __lock (path, ACCESS_READ);
  136.  
  137.   if (newlock)
  138.     {
  139.  
  140.       /* chroot() support - don't do a chdir if the path
  141.        * is a parent directory of the root directory
  142.        */
  143.       if (*u.u_root_directory) {
  144.     char dir[MAXPATHLEN];
  145.  
  146.     if (NameFromLock (newlock, dir, MAXPATHLEN)) {
  147.       if (dirisparent(dir,u.u_root_directory) == 1) {
  148.         errno = EACCES;
  149.         goto chdirerr;
  150.       }
  151.     }
  152.     else {
  153.       errno = __ioerr_to_errno (IoErr ());
  154.       goto chdirerr;
  155.     }
  156.       }
  157.  
  158.       oldlock = CurrentDir (newlock);
  159.  
  160.       if (u.u_startup_cd == (BPTR)-1)
  161.         u.u_startup_cd = oldlock;
  162.       else
  163.         __unlock (oldlock);
  164.  
  165.       set_dir_name_from_lock(newlock);
  166.  
  167.       syscall (SYS_sigsetmask, omask);
  168.       return 0;
  169.     }
  170.   error = __ioerr_to_errno (IoErr ());
  171.  
  172. chdirerr:
  173.   syscall (SYS_sigsetmask, omask);
  174.   errno = error;
  175.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno));
  176.   return -1;
  177. }
  178.  
  179. /* change the "root" directory to dir */
  180. int chroot(char *dir) {
  181.     int retval;
  182.  
  183.     retval = chdir(dir);
  184.  
  185.     if (retval == 0) {
  186.     BPTR rootlock = __lock(dir,ACCESS_READ);
  187.     if (rootlock)
  188.         NameFromLock(rootlock,u.u_root_directory,MAXPATHLEN);
  189.     else
  190.         retval = -1;
  191.     __unlock(rootlock);
  192.     }
  193.     return retval;
  194. }
  195.  
  196.  
  197.